package postgres

import (
	model "aggregation/model/dashboard"
	"context"
	manager "manager/model/entity"
	"time"
)

type market struct {
}

type shop struct {
}

var Market = &market{}

var Shop = &shop{}

// 门店已销售车辆
func (s *market) SoldBike(ctx context.Context) (int64, error) {
	var (
		count int64
		err   error
	)
	err = GetManagerDB(ctx).Model(&manager.Order{}).Where("status=?", 1).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, err
}

func (s *market) Distribute(ctx context.Context) (int64, error) {
	var (
		count int64
		err   error
	)
	err = GetManagerDB(ctx).Model(&manager.Ebike{}).Where("distribute_time > 0").Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, err
}
func (s *market) UnDistribute(ctx context.Context) (int64, error) {
	var (
		count int64
		err   error
	)
	err = GetManagerDB(ctx).Model(&manager.Ebike{}).Where("distribute_time = 0").Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, err
}
func (s *market) StoreTotal(ctx context.Context) (int64, error) {
	var (
		count int64
		err   error
	)
	db := GetManagerDB(ctx)
	err = db.Model(&manager.Store{}).Count(&count).Error
	if err != nil {
		return 0, err
	}
	return count, err
}

func (s *market) ProvinceSummary(ctx context.Context) ([]model.AreaStoreBike, error) {
	rows, err := GetManagerDB(ctx).Raw("SELECT code,region_name_c from regions where level = '1'").Rows()
	defer rows.Close()
	if err != nil {
		return nil, err
	}
	areas := make(map[int64]model.AreaStoreBike)
	for rows.Next() {
		var area model.AreaStoreBike
		rows.Scan(&area.AreaId, &area.AreaName)
		areas[area.AreaId] = area
	}

	// 直接查询门店所在区域门店个数
	rowStore, err := GetManagerDB(ctx).Raw("SELECT b.code,a.total from (SELECT count(1) as total,province_code FROM stores " +
		"GROUP BY province_code) a LEFT JOIN regions b on a.province_code =  b.code").Rows()
	defer rowStore.Close()
	if err != nil {
		return nil, err
	}
	for rowStore.Next() {
		var id, count int64
		rowStore.Scan(&id, &count)
		if area, ok := areas[id]; ok {
			area.StoreNum = count
			areas[id] = area
		}
	}

	// 查询门店所在区域设备的数量
	deviceNum, err := GetManagerDB(ctx).Raw("SELECT d.code,e.total from (SELECT b.province_code," +
		"COALESCE(sum(a.total),0) as total from (SELECT count(1) as total,store_id from ebikes GROUP BY store_id) a " +
		"RIGHT JOIN stores b on a.store_id = b.id GROUP BY province_code) e " +
		"LEFT JOIN regions d on d.code = e.province_code").Rows()
	defer deviceNum.Close()
	if err != nil {
		return nil, err
	}
	for deviceNum.Next() {
		var id, count int64
		deviceNum.Scan(&id, &count)
		if area, ok := areas[id]; ok {
			area.DeviceNum = count
			areas[id] = area
		}
	}
	result := make([]model.AreaStoreBike, 0, len(areas))
	for _, v := range areas {
		result = append(result, v)
	}
	return result, nil
}

// 门店排行,只有前5
func (s *market) StoreRank(ctx context.Context) ([]model.StoreSold, error) {
	var (
		rank []model.StoreSold
		err  error
	)
	rows, err := GetManagerDB(ctx).Raw("SELECT a.id,a.name,count(1) as count from stores a inner join orders o on a.id = o.store_id " +
		"group by a.id,a.name order by count desc limit 5").Rows()
	defer rows.Close()
	if err != nil {
		return nil, err
	}
	for rows.Next() {
		var r model.StoreSold
		rows.Scan(&r.StoreId, &r.StoreName, &r.Sold)
		rank = append(rank, r)
	}
	return rank, err
}

// 门店新增,按照某个时间区间新增数量
func (s *market) Increase(ctx context.Context, dur string, begin, end int64) ([]DurationCount, error) {
	var (
		month []DurationCount
		err   error
	)
	rows, err := GetManagerDB(ctx).Raw("SELECT DATE_TRUNC('"+dur+"', to_timestamp(created_at)) AS date, COUNT(1) from markets "+
		"where created_at > ? and created_at < ? GROUP BY date ORDER BY date;", begin, end).Rows()
	defer rows.Close()
	if err != nil {
		return nil, err
	}
	for rows.Next() {
		var record DurationCount
		rows.Scan(&record.Point, &record.Count)
		month = append(month, record)
	}
	return month, err
}

// 按天获取当前月份每日数据
func (s *market) IncreaseMonth(ctx context.Context, timestamp int64) ([]DurationCount, error) {
	begin, end := monthDuration(timestamp)
	return s.Increase(ctx, "day", begin, end)
}

// 以月为维度获取一年的数据
func (s *market) IncreaseYear(ctx context.Context, timestamp int64) ([]DurationCount, error) {
	end := time.Unix(timestamp, 0)
	begin := time.Date(end.Year(), 1, 1, 0, 0, 0, 0, end.Location())
	return s.Increase(ctx, "month", begin.Unix(), end.Unix())
}

// Count 绑定车辆
func (e *shop) Count(ctx context.Context) (int64, error) {

	var (
		err           error
		bindUserCount int64
	)
	err = GetManagerDB(ctx).Model(&manager.Store{}).Count(&bindUserCount).Error
	if err != nil {
		return 0, err
	}
	return bindUserCount, err
}

func (e *shop) CountByRange(ctx context.Context, begin, end time.Time) (DurationCount, error) {
	var (
		count DurationCount
		err   error
	)
	return count, err
}

// ThirtyDaysCount 时间节点所在的月份30天的数据
func (e *shop) ThirtyDaysCount(ctx context.Context, month time.Time) (DurationCounts, error) {
	rawSql := "SELECT DATE_TRUNC('day', to_timestamp(created_at)) AS day, COUNT(1) " +
		"from stores where created_at > ? and created_at < ? group by day"
	begin := time.Date(month.Year(), month.Month(), 1, 0, 0, 0, 0, month.Location())
	end := time.Date(month.Year(), month.Month()+1, 1, 0, 0, 0, 0, month.Location())
	return queryCount(GetManagerDB(ctx), rawSql, begin, end)
}

// TwelveMonthsCount 时间所在年份12个月的数据
func (e *shop) TwelveMonthsCount(ctx context.Context, year time.Time) (DurationCounts, error) {
	rawSql := "SELECT DATE_TRUNC('month', to_timestamp(created_at)) AS month, COUNT(1) " +
		"from stores where created_at > ? and created_at < ? group by month"
	begin := time.Date(year.Year(), 1, 1, 0, 0, 0, 0, year.Location())
	end := time.Date(year.Year(), 12, 30, 0, 0, 0, 0, year.Location())
	return queryCount(GetManagerDB(ctx), rawSql, begin, end)
}

// FiveYearsCount 最近五年的数据
func (e *shop) FiveYearsCount(ctx context.Context, year time.Time) (DurationCounts, error) {
	return DurationCounts{}, nil
}
